package com.m7788.screen.wxapi;

import java.io.StringReader;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.xmlpull.v1.XmlPullParser;

import android.content.Context;
import android.os.AsyncTask;
import android.util.Xml;

import com.m7788.util.AppUtil;
import com.m7788.util.Constant;
import com.tencent.mm.sdk.modelpay.PayReq;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
import com.tool.utils.DataUtil;
import com.tool.utils.LogUtil;

/**
 * 
 *    
 * 类名称：WXPayUtil   
 * 类描述：  微信支付类
 * 	       manifest文件 调用的界面   配置微信的appid
 * 创建人： huanghaishui   
 * 创建时间：2015-11-3 上午10:24:04   
 * 修改人：huanghaishui 
 * 修改时间：2015-11-3 上午10:24:04   
 * 修改备注：   
 * @version    
 *
 */
public class WXPayUtil {

	//微信appid
	public static final String WEIXINAPPID = "wx66fafab91c20da2c";
	// 应用签名
	public static final String PAY_QM = "71dee20c4280548988605b8c085beebb";
	// 商户号
	public static final String PAY_SHH = "1277556301";
	// API密钥，在商户平台设置
	public static final String PAY_API_KEY = "88d5f579b53f15154708112744ee87cc";


	private Context context;
	PayReq req;
	final IWXAPI msgApi;
	Map<String, String> resultunifiedorder;
	String price = 1 + "";
	String productName = "测试商品";
	String orderId = "";

	public WXPayUtil(Context context, String pName, String pPrice,
			String pOrderId) {
		this.context = context;
		msgApi = WXAPIFactory.createWXAPI(context, null);
		msgApi.registerApp(WEIXINAPPID);
		req = new PayReq();
		// 商品名称
		productName = pName;
		// 单位必须是  分
		price = pPrice;
		// 商户内部的订单号，最多只能32位字符
		orderId = pOrderId;
	}

	public void goPay() {
		if (DataUtil.isHaveApp("com.tencent.mm", context)) {
			new GetPrepayIdTask().execute();
		} else {
			DataUtil.showShortToast(context, "请先安装微信");
		}
	}

	// //////////////////////////////微信支付////////////////////////////////////////
	// 创建预付单
	private class GetPrepayIdTask extends
			AsyncTask<Void, Void, Map<String, String>> {
		@Override
		protected void onPreExecute() {
			// dialog = ProgressDialog.show(PayActivity.this,
			// getString(R.string.app_tip),
			// getString(R.string.getting_prepayid));
		}

		@Override
		protected void onPostExecute(Map<String, String> result) {
			resultunifiedorder = result;
			genPayReq();
		}

		@Override
		protected void onCancelled() {
			super.onCancelled();
		}

		@Override
		protected Map<String, String> doInBackground(Void... params) {

			String url = String
					.format("https://api.mch.weixin.qq.com/pay/unifiedorder");
			String entity = genProductArgs();
			byte[] buf = Util.httpPost(url, entity);
			String content = new String(buf);
			Map<String, String> xml = decodeXml(content);
			return xml;
		}
	}

	public Map<String, String> decodeXml(String content) {

		try {
			Map<String, String> xml = new HashMap<String, String>();
			XmlPullParser parser = Xml.newPullParser();
			parser.setInput(new StringReader(content));
			int event = parser.getEventType();
			while (event != XmlPullParser.END_DOCUMENT) {

				String nodeName = parser.getName();
				switch (event) {
				case XmlPullParser.START_DOCUMENT:
					break;
				case XmlPullParser.START_TAG:
					if ("xml".equals(nodeName) == false) {
						// 实例化student对象
						xml.put(nodeName, parser.nextText());
					}
					break;
				case XmlPullParser.END_TAG:
					break;
				}
				event = parser.next();
			}
			return xml;
		} catch (Exception e) {
		}
		return null;
	}

	private String genNonceStr() {
		Random random = new Random();
		// return
		// MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
		return MD5
				.getMessageDigest((String.valueOf(random.nextInt(10000)) + (genTimeStamp()))
						.getBytes());
	}

	private long genTimeStamp() {
		return System.currentTimeMillis() / 1000;
	}

	private String genOutTradNo() {
		Random random = new Random();
		// return
		// MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());

		return MD5
				.getMessageDigest((String.valueOf(random.nextInt(10000)) + (genTimeStamp()))
						.getBytes());
	}

	private String genPackageSign(List<NameValuePair> params) {
		StringBuilder sb = new StringBuilder();

		for (int i = 0; i < params.size(); i++) {
			sb.append(params.get(i).getName());
			sb.append('=');
			sb.append(params.get(i).getValue());
			sb.append('&');
		}
		sb.append("key=");
		sb.append(PAY_API_KEY);
		String packageSign = MD5.getMessageDigest(sb.toString().getBytes())
				.toUpperCase();
		return packageSign;
	}

	private String toXml(List<NameValuePair> params) {
		StringBuilder sb = new StringBuilder();
		sb.append("<xml>");
		for (int i = 0; i < params.size(); i++) {
			sb.append("<" + params.get(i).getName() + ">");
			sb.append(params.get(i).getValue());
			sb.append("</" + params.get(i).getName() + ">");
		}
		sb.append("</xml>");

		return sb.toString();
	}

	private String genProductArgs() {
		StringBuffer xml = new StringBuffer();

		try {
			String nonceStr = genNonceStr();
			String trade = genOutTradNo();
			xml.append("</xml>");

			List<NameValuePair> packageParams = new LinkedList<NameValuePair>();
			packageParams.add(new BasicNameValuePair("appid",
					WEIXINAPPID));
			packageParams.add(new BasicNameValuePair("body", productName));
			packageParams
					.add(new BasicNameValuePair("mch_id", PAY_SHH));
			packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));
			packageParams.add(new BasicNameValuePair("notify_url",
					"http://121.40.35.3/test"));
			packageParams.add(new BasicNameValuePair("out_trade_no", orderId));
			packageParams.add(new BasicNameValuePair("spbill_create_ip",
					"127.0.0.1"));
			packageParams.add(new BasicNameValuePair("total_fee", price + ""));
			packageParams.add(new BasicNameValuePair("trade_type", "APP"));
			String sign = genPackageSign(packageParams);
			packageParams.add(new BasicNameValuePair("sign", sign));

			String xmlstring = toXml(packageParams);
			xmlstring = new String(xmlstring.getBytes("UTF-8"), "ISO-8859-1");
			return xmlstring;

		} catch (Exception e) {
			LogUtil.e(Constant.APPTAG,
					"genProductArgs fail, ex = " + e.getMessage());
			return null;
		}
	}

	private void genPayReq() {

		req.appId = WEIXINAPPID;
		req.partnerId = PAY_SHH;
		// req.prepayId="wx20150902144356d242bba5170940634379";
		req.prepayId = resultunifiedorder.get("prepay_id");
		req.packageValue = "Sign=WXPay";
		req.nonceStr = genNonceStr();
		req.timeStamp = String.valueOf(genTimeStamp());

		List<NameValuePair> signParams = new LinkedList<NameValuePair>();
		signParams.add(new BasicNameValuePair("appid", req.appId));
		signParams.add(new BasicNameValuePair("noncestr", req.nonceStr));
		signParams.add(new BasicNameValuePair("package", req.packageValue));
		signParams.add(new BasicNameValuePair("partnerid", req.partnerId));
		signParams.add(new BasicNameValuePair("prepayid", req.prepayId));
		signParams.add(new BasicNameValuePair("timestamp", req.timeStamp));

		req.sign = genAppSign(signParams);
		LogUtil.e(Constant.APPTAG, "payInput");
		LogUtil.e(Constant.APPTAG, signParams.toString());
		msgApi.registerApp(WEIXINAPPID);
		msgApi.sendReq(req);
	}

	private String genAppSign(List<NameValuePair> params) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < params.size(); i++) {
			sb.append(params.get(i).getName());
			sb.append('=');
			sb.append(params.get(i).getValue());
			sb.append('&');
		}
		sb.append("key=");
		sb.append(PAY_API_KEY);
		String appSign = MD5.getMessageDigest(sb.toString().getBytes())
				.toUpperCase();
		return appSign;
	}

}
